package com.example.java_gobang.game;

import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

//完成匹配功能
@Component
public class Matcher {
    //创建三个匹配队列
    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private RoomManager roomManager;
    private ObjectMapper objectMapper = new ObjectMapper();

    //操作匹配队列 的方法

    //  把玩家放到匹配队列
    public void add(User user){
        if (user.getScore() < 2000){
            synchronized (normalQueue){
                normalQueue.offer(user);
                normalQueue.notify();
            }

            System.out.println("把玩家"+user.getUsername()+"加入到了 normalQueue 中！");


        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue){
                highQueue.offer(user);
                highQueue.notify();
            }

            System.out.println("把玩家"+user.getUsername()+"加入到了 highQueue 中！");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }

            System.out.println("把玩家"+user.getUsername()+"加入到了 veryHighQueue 中！");
        }
    }

    // 把玩家从匹配队列中移除
    public void remove(User user){
        if (user.getScore() < 2000){
            synchronized (normalQueue){
                normalQueue.remove(user);
            }
            System.out.println("把玩家"+user.getUsername()+"移除normalQueue队列");
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue){
                highQueue.remove(user);
            }
            System.out.println("把玩家"+user.getUsername()+"移除highQueue队列");

        }else {
            synchronized (veryHighQueue){
                veryHighQueue.remove(user);
            }
            System.out.println("把玩家"+user.getUsername()+"移除veryHighQueue队列");

        }
    }

    public Matcher(){
        //创建三个线程，分别针对三个匹配队列 (匿名内部类)
        Thread t1 = new Thread(){
            @Override
            public void run() {
                //扫描normalQueue
                while (true){
                    handlerMatch(normalQueue);
                }
            }
        };
        t1.start();
        Thread t2 = new Thread(){
            @Override
            public void run() {

                while (true){
                    handlerMatch(highQueue);
                }
            }
        };
        t2.start();
        Thread t3 = new Thread(){
            @Override
            public void run() {

                while (true){
                    handlerMatch(veryHighQueue);
                }
            }
        };
        t3.start();
    }

    private void handlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue){
            try {
                // 很可能队列初始情况为0，用while循环检查，不能用if（匹配成功需要有两个玩家）
                while (matchQueue.size() < 2){
                    matchQueue.wait();
                    return;
                }
                //从队列中取出两个玩家
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配出了两个玩家："+player1.getUsername()+" , "+player2.getUsername());
                //获取玩家的websocket的会话，告诉玩家 排到了
                WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserId());
                //理论上来说，匹配队列中的玩家一定是在线状态（前面已经处理过，断开连接的玩家会被移除匹配队列
                //为了谨慎，再进行一次判断
                if (session1 == null){
                    //玩家1不在线就把玩家2放回到匹配队列中
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null){
                    //玩家2不在线就把玩家1放回到匹配队列中
                    matchQueue.offer(player1);
                    return;
                }
                //TODO 把这两个玩家放到一个游戏房间中
                Room room = new Room();
                roomManager.add(room,player1.getUserId(),player2.getUserId());

                //给玩家反馈信息 匹配到了
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));

                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));
            }catch (IOException | InterruptedException e){
                e.printStackTrace();
            }
        }


    }
}
